﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Core.Utility.Helper
{
    /// <summary>
    /// 程序集助手类
    /// </summary>
    public static class AssemblyHelper
    {
        /// <summary>
        /// 获取当前类包含程序集及命名空间的完全限定名称，通常用于加载功能的完全限定名称
        /// </summary>
        /// <param name="type"></param>
        /// <returns>程序集名(不含扩展名);类型所在的命名空间.类型名</returns>
        public static string AssemblyFullName(this Type type)
        {
            string res = "";
            if (type != null)
            {
                var assemblyName = type.Assembly.GetName().Name;
                var typeFullName = type.FullName;
                res = $"{assemblyName};{typeFullName}";
            }
            return res;
        }


        /// <summary>
        /// 获取程序集的接口实现类
        /// </summary>
        /// <param name="assembly">程序集</param>
        /// <param name="interfaceType">接口类型，例如：typeof(Interface) </param>
        /// <returns></returns>
        public static List<Type> InterfaceImplementationClass(this Assembly assembly,Type interfaceType)
        {
            var typeList = assembly.GetTypes().Where(p => p.GetInterfaces().Contains(interfaceType)).ToList();
            return typeList;
        }


        /// <summary>
        /// 通过文件名加载指定程序集
        /// </summary>
        /// <param name="directory">搜索目录</param>
        /// <param name="regexAssemblyFileName">正则 程序集文件名，如^Module.Developer.Tool.Sf.(dll|exe)$</param>
        /// <param name="searchChildDirectory"></param>
        public static void LoadAssemblyByFileNameRegex(string directory,string regexAssemblyFileName,bool searchChildDirectory = false)
        {
            List<string> assemblieList = new List<string>();
            List<string> assemblyFileList = FileHelper.GetFiles(directory, regexAssemblyFileName, searchChildDirectory);
            foreach (var assemblyFile in assemblyFileList)
            {
                try
                {
                    var assemblyName = AssemblyName.GetAssemblyName(assemblyFile);
                    if (!string.IsNullOrEmpty(assemblyName?.Name))
                    {
                        assemblieList.Add(assemblyName.Name);
                    }
                }
                catch
                {

                }
            }
            LoadAssembly(assemblieList);
        }

        /// <summary>
        /// 通过AssemblyName列表加载配置文件中的程序集
        /// </summary>
        /// <returns></returns>
        public static void LoadAssembly(IEnumerable<string> assemblyNamesToScan)
        {
            var loadedAssemblyList = AppDomain.CurrentDomain.GetAssemblies();
            foreach(var item in assemblyNamesToScan)
            {
                if(!loadedAssemblyList.Any(p=> p.GetName().Name == item))
                {
                    var res = Assembly.Load(item);                    
                }
            }
        }
    }
}
